package com.kodin.webview;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ProgressBar;

import androidx.appcompat.app.AppCompatActivity;

import com.blankj.utilcode.constant.PermissionConstants;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.ConvertUtils;
import com.blankj.utilcode.util.EncodeUtils;
import com.blankj.utilcode.util.EncryptUtils;
import com.blankj.utilcode.util.FileIOUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.PermissionUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.blankj.utilcode.util.UriUtils;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.tencent.smtt.sdk.ValueCallback;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import io.microshow.rxffmpeg.RxFFmpegCommandList;
import io.microshow.rxffmpeg.RxFFmpegInvoke;
import io.microshow.rxffmpeg.RxFFmpegProgress;
import io.microshow.rxffmpeg.RxFFmpegSubscriber;

/**
 * uniapp页面
 */
public class TXWebViewActivity extends AppCompatActivity {
    private String TAG = "cmy_" + this.getClass().getSimpleName();
    public static String EXP_EXPERT_URL = "expert_url";
    public static String EXP_EXPERT_TOKEN = "expert_token";
    public static String SHOW_TITLE = "show_title";// 是不是显示标题栏目
    public static String IS_AVATAR = "is_avatar";// 是不是头像
    private WebView web_view_content;
    private ProgressBar progress_bar;
    private String my_url, token;
    private Map<String, String> map = new HashMap<>();
    private boolean isAvatar = false;

    @SuppressLint("SourceLockedOrientationActivity")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tx_web_detail_layout);
        my_url = getIntent().getStringExtra(EXP_EXPERT_URL);
        token = getIntent().getStringExtra(EXP_EXPERT_TOKEN);
        isAvatar = getIntent().getBooleanExtra(IS_AVATAR, false);
        LogUtils.e(TAG + my_url + map);
        if (TextUtils.isEmpty(my_url)) {
            ToastUtils.showLong("地址为空");
            my_url = "file:///android_asset/javascript.html";
        }
        initView(my_url);
    }


    private void initView(String url) {
        if (!TextUtils.isEmpty(token)) {
            map.put("token", token);
        }
        progress_bar = findViewById(R.id.progress_bar);
        web_view_content = findViewById(R.id.web_view_content);
        //可以关闭定位功能，内核默认是开启的
        web_view_content.getSettings().setGeolocationEnabled(false);
        WebSettings webSettings = web_view_content.getSettings();
        // h5
        //如果访问的页面中要与Javascript交互，则webview必须设置支持Javascript
        webSettings.setJavaScriptEnabled(true);
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        webSettings.setTextZoom(100);

        webSettings.setDomStorageEnabled(true); // 开启 DOM storage API 功能
        web_view_content.addJavascriptInterface(new AndroidToJs(new AndroidToJs.OnJs() {
            @Override
            public void closeWindow() {
                finish();
            }

            @Override
            public void closeApp() {
                AppUtils.exitApp();
            }

            @Override
            public void deleteImage(String count) {
                LogUtils.e(TAG, count);
                selectCount = Integer.parseInt(count);
            }

            @Override
            public void startNewWebView(String url) {
                LogUtils.e(TAG, url);
                startTxWeb(url);
            }
        }), "android");//AndroidtoJS类对象映射到js的android对象
        web_view_content.setWebViewClient(new MyWebViewClient());
        web_view_content.setWebChromeClient(new MyWebChromeClient());
        web_view_content.loadUrl(url, map);
        web_view_content.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                final WebView.HitTestResult hitTestResult = web_view_content.getHitTestResult();
                // 如果是图片类型或者是带有图片链接的类型
                if (hitTestResult.getType() == WebView.HitTestResult.IMAGE_TYPE ||
                        hitTestResult.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
                    // 弹出保存图片的对话框
                    new AlertDialog.Builder(TXWebViewActivity.this)
                            .setItems(new String[]{"保存图片"}, (dialog, which) -> {
                                String pic = hitTestResult.getExtra();//获取图片
                                LogUtils.e(TAG, " 获取到的图片地址为  ：" + pic);
                                MyDownloadManager myDownloadManager = new MyDownloadManager();
                                switch (which) {
                                    case 0:
                                        myDownloadManager.addDownloadTask(pic);
                                        break;
                                }
                            })
                            .show();
                    return true;
                }
                return false;
            }
        });
    }

    public static void startTxWeb(Context context, String path) {
        Intent intent = new Intent(context, TXWebViewActivity.class);
        intent.putExtra(TXWebViewActivity.EXP_EXPERT_URL, path);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(TXWebViewActivity.SHOW_TITLE, false);
        context.startActivity(intent);
    }

    /**
     * 启动 新的webview
     *
     * @param path
     */
    private void startTxWeb(String path) {
        Intent intent = new Intent(this, TXWebViewActivity.class);
        intent.putExtra(TXWebViewActivity.EXP_EXPERT_URL, path);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(TXWebViewActivity.SHOW_TITLE, true);
        startActivity(intent);
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            if (web_view_content.canGoBack()) {
                web_view_content.goBack();
            } else {
                finish();
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    private ValueCallback<Uri[]> uploadMessageAboveL;
    private long start = System.currentTimeMillis();

    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            LogUtils.e(TAG + url + map);
            view.loadUrl(url, map);
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            start = System.currentTimeMillis();
            //设定加载开始的操作
            LogUtils.e(TAG + url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            //设定加载结束的操作
            LogUtils.e(TAG + url + map, System.currentTimeMillis() - start);
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            LogUtils.e(TAG + failingUrl + map);
        }

        @Override
        public void onLoadResource(WebView view, String url) {
            //设定加载资源的操作
            LogUtils.e(TAG + url);
        }
    }

    private class MyWebChromeClient extends WebChromeClient {
        @Override
        public void onReceivedTitle(WebView webView, String s) {
            super.onReceivedTitle(webView, s);
        }

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            if (newProgress == 100) {
                progress_bar.setVisibility(View.GONE);
            } else {
                if (progress_bar.getVisibility() == View.GONE) {
                    progress_bar.setVisibility(View.VISIBLE);
                }
                progress_bar.setProgress(newProgress);
            }

            super.onProgressChanged(view, newProgress);
        }

        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
            LogUtils.e(TAG);
            uploadMessageAboveL = filePathCallback;
            try {
                doStartScan();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return true;
        }
    }

    private void doStartScan() {
        // 进入相册
        PictureSelector.create(this)
                .openGallery(PictureMimeType.ofAll())
                .imageEngine(GlideEngine.createGlideEngine()) // 这里就是设置图片加载引擎
                .maxSelectNum(isAvatar ? 1 : (9 - selectCount))
                .isWeChatStyle(true)
                .isCompress(true)// 是否压缩
                .minimumCompressSize(1 * 1024)
                .isEnableCrop(isAvatar ? true : false)
                .withAspectRatio(1, 1)
                .rotateEnabled(false)
                .forResult(PictureConfig.CHOOSE_REQUEST);
    }

    private int selectCount = 0;
    private int mimeType = PictureMimeType.ofImage();
    private String outFullPath;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        LogUtils.e(TAG + String.format("requestCode=%d,resultCode=%d", requestCode, resultCode));
        //如果是文件选择
        super.onActivityResult(requestCode, resultCode, data);
        if (data == null) {
            if (uploadMessageAboveL != null) {
                uploadMessageAboveL.onReceiveValue(null);
                uploadMessageAboveL = null;
            }
        } else {
            if (requestCode == PictureConfig.CHOOSE_REQUEST || requestCode == PictureConfig.REQUEST_CAMERA) {
                List<LocalMedia> result = PictureSelector.obtainMultipleResult(data);
                selectCount += result.size();
                Uri[] results = new Uri[result.size()];
                String filePath = "";
                for (int i = 0; i < result.size(); i++) {
                    LocalMedia localMedia = result.get(i);
                    LogUtils.e(GsonUtils.toJson(localMedia));
                    if (!TextUtils.isEmpty(localMedia.getCompressPath())) {
                        filePath = localMedia.getCompressPath();
                    } else {
                        filePath = localMedia.getRealPath();
                    }
                    results[i] = UriUtils.file2Uri(new File(filePath));
                    mimeType = PictureMimeType.getMimeType(localMedia.getMimeType());
                    if (mimeType == PictureMimeType.ofVideo()) {
                        outFullPath = PathUtils.getExternalMoviesPath() + "/" + System.currentTimeMillis() + ".mp4";
                        common(filePath, outFullPath);
                        return;
                    }
                }
                if (uploadMessageAboveL != null) {
                    uploadMessageAboveL.onReceiveValue(results);
                    uploadMessageAboveL = null;
                }
            }
        }

    }

    private void analyticalSelectResults(ArrayList<LocalMedia> result) {
        for (LocalMedia media : result) {
            LogUtils.e(GsonUtils.toJson(media));
        }
    }

    ProgressDialog mProgressDialog;// 进度条等待对话框

    private void common(String srcFullPath, String outFullPath) {
        onShowProgress();
        String text = "ffmpeg -y -i %s -vf boxblur=25:5 -preset superfast %s";
        // 支持libx264编码库，可以使压缩后的视频体积变的极小，清晰度还保持着很高清
        text = "ffmpeg -y -i %s -b 2097k -r 30 -vcodec libx264 -preset superfast %s";
        text = String.format(text, srcFullPath, outFullPath);
        LogUtils.e(text, srcFullPath, outFullPath);
        String[] commands = text.split(" ");
//        commands = getBoxblur(srcFullPath, outFullPath);
        RxFFmpegInvoke.getInstance().runCommandRxJava(commands).subscribe(myRxFFmpegSubscriber);
    }

    public static String[] getBoxblur(String srcFullPath, String outFullPath) {
        RxFFmpegCommandList cmdlist = new RxFFmpegCommandList();
        cmdlist.append("-i");
        cmdlist.append(srcFullPath);
        cmdlist.append("-vf");
        cmdlist.append("boxblur=5:1");
        cmdlist.append("-preset");
        cmdlist.append("superfast");
        cmdlist.append(outFullPath);
        return cmdlist.build();
    }

    RxFFmpegSubscriber myRxFFmpegSubscriber = new RxFFmpegSubscriber() {
        @Override
        public void onFinish() {
            LogUtils.e(RxFFmpegInvoke.getInstance().getMediaInfo(outFullPath));
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    onDismissProgress();
                }
            });
        }

        @Override
        public void onProgress(int progress, long progressTime) {
            LogUtils.e(progress, progressTime);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    setProgressProgress(progress, progressTime);
                }
            });
        }

        @Override
        public void onCancel() {
            LogUtils.e("");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    onDismissProgress();
                }
            });
        }

        @Override
        public void onError(String message) {
            LogUtils.e(message);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    onDismissProgress();
                }
            });
        }
    };

    private void setProgressProgress(int progress, long progressTime) {
        if (mProgressDialog != null) {
            mProgressDialog.setProgress(progress);
            //progressTime 可以在结合视频总时长去计算合适的进度值
            mProgressDialog.setMessage("已处理progressTime=" + (double) progressTime / 1000000 + "秒");
        }
    }

    private void onShowProgress() {
        if (mProgressDialog == null) {
            mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setTitle("正在压缩视频");
            mProgressDialog.setMax(100);
            mProgressDialog.setCancelable(false);
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        }
        mProgressDialog.show();
    }

    private void onDismissProgress() {
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        LogUtils.e(TAG);
    }

    @Override
    protected void onPause() {
        super.onPause();
        LogUtils.e(TAG);
    }

    @Override
    protected void onStop() {
        super.onStop();
        LogUtils.e(TAG);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        LogUtils.e(TAG);
        if (myRxFFmpegSubscriber != null) myRxFFmpegSubscriber.dispose();
    }

    private class MyDownloadManager {
        public void addDownloadTask(String urlPath) {
            ThreadUtils.executeByCached(new ThreadUtils.SimpleTask<String>() {
                @Override
                public String doInBackground() throws Throwable {
                    String fileName = EncryptUtils.encryptMD5ToString(urlPath) + ".jpg";
                    File savePath = new File(PathUtils.getExternalDcimPath(), fileName); // 下载文件路径
                    if (savePath.exists()) {
                        // 文件存在则已下载
                        return savePath.getAbsolutePath();
                    }
                    try {
                        byte[] bs = new byte[1024];
                        int len;
                        URL url = new URL(urlPath);
                        InputStream is = url.openStream();
                        OutputStream os = new FileOutputStream(savePath, true);
                        while ((len = is.read(bs)) != -1) {
                            os.write(bs, 0, len);
                        }
                        is.close();
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return savePath.getAbsolutePath();
                }

                @Override
                public void onSuccess(String result) {
                    ToastUtils.showShort("保存成功" + result);
                    MediaScannerConnection.scanFile(TXWebViewActivity.this, new String[]{result}, null, null);
                    LogUtils.e(result);
                }
            });
        }
    }
}
